package com.lc.fbtp.draftmsg.core.schema;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.SAXException;

/**
 * schema缓存
 * @author yeyun20029
 *
 */
public class ValidatorCache {

	private static final Logger logger = LoggerFactory.getLogger(ValidatorCache.class);
	private static final  Map<String, Validator> cache = new ConcurrentHashMap<String, Validator>();
	
	/**
	 * 初始化schema实例
	 */
	private static void initCache(){
		SchemaFactory schemaFactory = SchemaFactory
				  .newInstance("http://www.w3.org/2001/XMLSchema");
		String home = System.getenv("DRAFT_HOME");
		String schemaPath = home + File.separator + "schema";
		File homeDir = new File(schemaPath);
		if(!homeDir.exists()||homeDir.isFile()) {
			try {
				throw new RuntimeException("环境变量下不存在schema目录，无法初始化报文格式校验!");
			} catch (Exception e) {
				logger.error("初始化报文schema错误", e);
			}
		}
		
		List<File> fileList = readSchemaFile(homeDir);
		for (File file : fileList) {
			String fileName = file.getName();
			String mesgType = fileName.substring(0, fileName.lastIndexOf(".xsd"));
			try {
				Schema schema = schemaFactory.newSchema(file);
				Validator newValidator = schema.newValidator();
				cache.put(mesgType, newValidator);
			} catch (SAXException e) {
				logger.error("报文类型{}实例化Schema失败", mesgType);
				logger.error(file.getAbsolutePath() + "文件存在未知错误", e);
			}
		}
	}
	
	/**
	 * 读取schema文件
	 * @param dir
	 * @return
	 */
	private static List<File> readSchemaFile(File dir){
		List<File> fileList = new ArrayList<File>();
		File[] listFiles = dir.listFiles();
		if(listFiles==null){
			return fileList;
		}
		for (File file : listFiles) {
			if(file.isDirectory()){
				fileList.addAll(readSchemaFile(file));
			} else {
				String fileName = file.getName();
				if(fileName.endsWith(".xsd")){
					fileList.add(file);
				}
			}
		}
		return fileList;
	}
	
	/**
	 * 获取Schema实例
	 * @param mesgType
	 * @return
	 */
	public static Validator getValidator(String mesgType){
		if(cache.isEmpty()){
			initCache();
		}
		return cache.get(mesgType);
	}
}
